﻿using System;
using System.Diagnostics;
using System.Windows;
using Coding4Fun.BoxingBots.Common;
using Coding4Fun.BoxingBots.Communication;
using Coding4Fun.Kinect.KinectService.Common;
using Coding4Fun.Kinect.KinectService.WpfClient;

namespace Coding4Fun.BoxingBots.Scoreboard
{
	class UserConsole : IDisposable
	{
		public event EventHandler<ColorFrameReadyEventArgs> ColorFrameReady;
		public event EventHandler<SkeletonFrameReadyEventArgs> SkeletonFrameReady;
		public event EventHandler<AudioFrameReadyEventArgs> AudioFrameReady;

		private ColorClient _colorClient;
		private SkeletonClient _skeletonClient;
		private AudioClient _audioClient;

		private SocketClient<GameStatePacket, MovementDescriptorPacket> _dataClient;

		public Robot Robot { get; set; }

		public bool IsConnected
		{
			get 
			{
				return	((Properties.Settings.Default.UseKinectServiceFromConsoles && 
						(_colorClient != null &&
						_skeletonClient != null &&
						_colorClient.IsConnected && 
						_skeletonClient.IsConnected)) ||
						(_dataClient != null && _dataClient.IsConnected)) &&
						(Properties.Settings.Default.MuteKinectAudio || (_audioClient != null && _audioClient.IsConnected));
			}
		}

		public void Connect(string address, int colorPort, int skeletonPort, int audioPort, int dataPort)
		{
			if(Properties.Settings.Default.UseKinectServiceFromConsoles)
			{
				_colorClient = new ColorClient();
				_colorClient.ColorFrameReady += _colorClient_ColorFrameReady;
				_colorClient.Connect(address, colorPort);

				_skeletonClient = new SkeletonClient();
				_skeletonClient.SkeletonFrameReady += _skeletonClient_SkeletonFrameReady;
				_skeletonClient.Connect(address, skeletonPort);

				if(!Properties.Settings.Default.MuteKinectAudio)
				{
					_audioClient = new AudioClient();
					_audioClient.AudioFrameReady += _audioClient_AudioFrameReady;
					_audioClient.Connect(address, audioPort);
				}
			}

			_dataClient = new SocketClient<GameStatePacket, MovementDescriptorPacket>();
			_dataClient.ConnectionCompleted += DataClientConnectionCompleted;
			_dataClient.PacketReceived += DataClientPacketReceived;
			_dataClient.Connect(address, dataPort);
		}

		void DataClientConnectionCompleted(object sender, Communication.ConnectionEventArgs e)
		{
			Debug.WriteLine("Connection from ScoreBoard to UserConsole: " + e.Connected);

			if(!e.Connected)
				MessageBox.Show("Connection from ScoreBoard to UserConsole failed");
		}

		void DataClientPacketReceived(object sender, PacketReceivedEventArgs<MovementDescriptorPacket> e)
		{
			Debug.WriteLine("MovementDescriptorPacket (scoreboard): " + e.Packet);

			// TODO: Update the scoreboard UI with the values

			if(e.Packet.PunchLeft || e.Packet.PunchRight)
				AudioPlayer.PlayCue(SoundCue.Punch);

			e.Packet.Health = Robot.Health;
            e.Packet.PopHead = (e.Packet.Health <= 0);

			Robot.Send(e.Packet);
		}

		public void Send(GameStatePacket gsp)
		{
			if(_dataClient != null)
				_dataClient.Send(gsp);
		}

		private void _colorClient_ColorFrameReady(object sender, ColorFrameReadyEventArgs e)
		{
			if(ColorFrameReady != null)
				ColorFrameReady(this, e);
		}

		void _skeletonClient_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
		{
			if(SkeletonFrameReady != null)
				SkeletonFrameReady(this, e);
		}

		void _audioClient_AudioFrameReady(object sender, AudioFrameReadyEventArgs e)
		{
			if(AudioFrameReady != null)
				AudioFrameReady(this, e);
		}

		public void Dispose()
		{
			if (Robot != null)
				Robot.Dispose();

			if(_colorClient != null)
				_colorClient.Disconnect();

			if(_audioClient != null)
				_audioClient.Disconnect();

			if(_skeletonClient != null)
				_skeletonClient.Disconnect();

			if(_dataClient != null)
				_dataClient.Disconnect();
		}
	}
}
